#pragma once

enum {
    OP_LOAD,
    OP_MOVE,
    OP_POP,
    OP_COPY,

    OP_CASTB,
    OP_CASTI,
    OP_CASTL,
    OP_CASTF,
    OP_CASTD,

    OP_ADDI,
    OP_ADDL,
    OP_ADDF,
    OP_ADDD,
    OP_SUBI,
    OP_SUBL,
    OP_SUBF,
    OP_SUBD,
    OP_MULI,
    OP_MULL,
    OP_MULF,
    OP_MULD,
    OP_DIVI,
    OP_DIVL,
    OP_DIVF,
    OP_DIVD,

    OP_MODI,
    OP_MODL,
    OP_BANDI,
    OP_BANDL,
    OP_BORI,
    OP_BORL,
    OP_BXORI,
    OP_BXORL,
    OP_SHLI,
    OP_SHLL,
    OP_SHRI,
    OP_SHRL,
    OP_BNOTI,
    OP_BNOTL,

    OP_EQ,
    OP_NE,
    OP_LE,
    OP_GE,
    OP_LT,
    OP_GT,
    OP_BOOL,

    OP_JUMP,
    OP_JUMPIF,

    OP_END,
};


#define duaReadCode(CODE, PREFIX) \
    PREFIX##R1 = (((CODE) >> 22) & 0x3ff); \
    PREFIX##R2= (((CODE) >> 12) & 0x3ff); \
    PREFIX##Flag = (((CODE) >> 7) & 0x1f); \
    PREFIX##Op = ((CODE) & 0x7f)

#define duaMakeCode(OP, R1, R2, FLAG) \
    ((((R1) << 22) & 0xffC00000) \
    | (((R2)  << 12) & 0x3ff000) \
    | (((FLAG) << 7) & 0xf80) \
    | ((OP) & 0x7F))
